//
//  NDNetworkService.swift
//  NyamanDana
//
//  Created by 李永彬 on 2025/10/24.
//

import Foundation
import Alamofire

// MARK: - 域名配置
enum NDAPIDomain: String {
    case api = "http://149.129.255.14:10703/reduceosity"
    case h5 = "http://149.129.255.14:10703/"
    var baseURL: String { rawValue }
}

// MARK: - 内容类型
enum NDContentType {
    case formUrlEncoded
    case json
    case multipartForm
    
    var headerValue: String {
        switch self {
        case .formUrlEncoded: return "application/x-www-form-urlencoded"
        case .json: return "application/json"
        case .multipartForm: return "multipart/form-data"
        }
    }
    
    var encoding: ParameterEncoding {
        switch self {
        case .formUrlEncoded: return URLEncoding.default
        case .json: return JSONEncoding.default
        case .multipartForm: return URLEncoding.default
        }
    }
}

// MARK: - 错误类型
enum NDNetworkError: Error, LocalizedError {
    case invalidURL
    case encodingFailed
    case decodingFailed(Error)
    case networkError(Error)
    case serverError(code: Int, message: String)
    case unauthorized
    case timeout
    case emptyData
    case unknown
    
    var errorDescription: String? {
        switch self {
        case .invalidURL:
            return "Invalid URL"
        case .encodingFailed:
            return "Parameter encoding failed"
        case .decodingFailed(let error):
            return error.localizedDescription
        case .networkError(let error):
            return error.localizedDescription
        case .serverError(_, let message):
            return message
        case .unauthorized:
            return "Unauthorized access"
        case .timeout:
            return "Request timeout"
        case .emptyData:
            return "Empty response data"
        case .unknown:
            return "Unknown error occurred"
        }
    }
}

// 定义数据模型
struct NDResponse<T: Codable>: Codable {
    let granally: Int  // Changed to Int type
    let clositious: String
    let aurth: T?
    
    var isSuccess: Bool { granally == 0 }
    var isUnauthorized: Bool { granally == -2 }
    
    enum CodingKeys: String, CodingKey {
        case granally
        case clositious
        case aurth
    }
    
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        // 处理可能的类型转换
        granally = try {
            if let intValue = try? container.decode(Int.self, forKey: .granally) {
                return intValue
            }
            let stringValue = try container.decode(String.self, forKey: .granally)
            guard let intValue = Int(stringValue) else {
                throw DecodingError.dataCorruptedError(
                    forKey: .granally,
                    in: container,
                    debugDescription: "Cannot convert granally to Int"
                )
            }
            return intValue
        }()
        
        clositious = try container.decode(String.self, forKey: .clositious)
        aurth = try container.decodeIfPresent(T.self, forKey: .aurth)
    }
}

// MARK: - 网络服务
final class NDNetworkService {
    static let shared = NDNetworkService()
    
    private let session: Session
    let requestBuilder = NDRequestBuilder()
    
    private init() {
        let configuration = URLSessionConfiguration.af.default
        configuration.timeoutIntervalForRequest = 60
        configuration.timeoutIntervalForResource = 60
        self.session = Session(configuration: configuration)
    }

    // MARK: - 公开方法 - 返回原始 Data
    
    func request(
        _ endpoint: NDEndpoint,
        completion: @escaping (Result<Data, NDNetworkError>) -> Void
    ) {
        do {
            let request = try requestBuilder.buildRequest(from: endpoint)
            performRequest(request: request, completion: completion)
        } catch {
            completion(.failure(error as? NDNetworkError ?? .unknown))
        }
    }
    
    func upload(
        _ endpoint: NDUploadEndpoint,
        completion: @escaping (Result<Data, NDNetworkError>) -> Void
    ) {
        do {
            let request = try requestBuilder.buildRequest(from: endpoint)
            performUpload(request: request, endpoint: endpoint, completion: completion)
        } catch {
            completion(.failure(error as? NDNetworkError ?? .unknown))
        }
    }
    
    // MARK: - 私有方法
    private func performRequest(
        request: URLRequest,
        completion: @escaping (Result<Data, NDNetworkError>) -> Void
    ) {
        session.request(request)
            .validate()
            .responseData { response in
                self.handleResponse(response, completion: completion)
            }
    }
    
    private func performUpload(
        request: URLRequest,
        endpoint: NDUploadEndpoint,
        completion: @escaping (Result<Data, NDNetworkError>) -> Void
    ) {
        session.upload(
            multipartFormData: { multipartFormData in
                // 添加文件数据
                multipartFormData.append(
                    endpoint.fileData,
                    withName: endpoint.formDataName,
                    fileName: endpoint.fileName,
                    mimeType: endpoint.mimeType
                )
                
                // 添加普通参数
                endpoint.parameters?.forEach { key, value in
                    if let stringValue = value as? String {
                        multipartFormData.append(stringValue.data(using: .utf8)!, withName: key)
                    } else if let numberValue = value as? NSNumber {
                        multipartFormData.append(numberValue.stringValue.data(using: .utf8)!, withName: key)
                    }
                }
                
                // 添加公共参数
                self.requestBuilder.commonParameters.forEach { key, value in
                    if let stringValue = value as? String {
                        multipartFormData.append(stringValue.data(using: .utf8)!, withName: key)
                    } else if let numberValue = value as? NSNumber {
                        multipartFormData.append(numberValue.stringValue.data(using: .utf8)!, withName: key)
                    }
                }
            },
            with: request
        )
        .validate()
        .responseData { response in
            self.handleResponse(response, completion: completion)
        }
    }
    
    private func handleResponse(
        _ response: AFDataResponse<Data>,
        completion: @escaping (Result<Data, NDNetworkError>) -> Void
    ) {
        switch response.result {
        case .success(let data):
            handleSuccessResponse(data: data, completion: completion)
        case .failure(let error):
            let networkError = handleFailureResponse(error: error, data: response.data)
            completion(.failure(networkError))
        }
    }
    
    private func handleSuccessResponse(
        data: Data,
        completion: @escaping (Result<Data, NDNetworkError>) -> Void
    ) {
        // 打印响应日志
        if let jsonString = String(data: data, encoding: .utf8) {
            print("📥 Response: \(jsonString)")
        }
        
        do {
            // 首先解析响应状态
            let statusResponse = try JSONDecoder().decode(NDResponse<EmptyTemp>.self, from: data)
            
            if statusResponse.isUnauthorized {
                handleUnauthorizedError(message: statusResponse.clositious)
                completion(.failure(.unauthorized))
                return
            }
            
            if !statusResponse.isSuccess {
                completion(.failure(.serverError(
                    code: statusResponse.granally,
                    message: statusResponse.clositious
                )))
                return
            }
            
            // 业务成功，返回原始 Data
            completion(.success(data))
        } catch {
            // 如果解析状态失败，但仍然有数据，返回数据
            if !data.isEmpty {
                completion(.success(data))
            } else {
                completion(.failure(.decodingFailed(error)))
            }
        }
    }
    
    private func handleFailureResponse(error: AFError, data: Data?) -> NDNetworkError {
        if let underlyingError = error.underlyingError {
            return .networkError(underlyingError)
        }
        
        if error.isExplicitlyCancelledError {
            return .unknown
        }
        
        if error.isSessionTaskError {
            return .timeout
        }
        
        // 尝试解析服务器返回的错误信息
        if let data = data {
            do {
                let response = try JSONDecoder().decode(NDResponse<EmptyTemp>.self, from: data)
                return .serverError(
                    code: response.granally,
                    message: response.clositious
                )
            } catch {
                // 忽略解析错误，返回通用错误
            }
        }
        
        return .unknown
    }
    
    private func handleUnauthorizedError(message: String) {
        print("🔐 Unauthorized: \(message)")
        // 发送通知或跳转到登录页面
        // NotificationCenter.default.post(name: .NDNotLoginNotification, object: nil)
    }
}

// MARK: - 请求构建器
final class NDRequestBuilder {
    
    var commonParameters: [String: Any] {
        let appName = NDUserDefaults.shared.retrieveText(for: NDAppNameKey) ?? "NyamanDana"
        return [
            "vermer": "ios",
            "downor": Bundle.main.appVersion,
            "microful": UIDevice.current.modelName,
            "denade": DeviceIdentifier.vendorIdentifier,
            "petr": UIDevice.current.systemVersion,
            "gem": appName,
            "pur": NDUserDefaults.shared.retrieveText(for: NDAccountIdentifierKey) ?? "",
            "sibilaster": DeviceIdentifier.vendorIdentifier,
            "governmentic": NDUserDefaults.shared.retrieveText(for: NDRegionCodeKey) ?? ""
        ]
    }
    
    private var commonHeaders: HTTPHeaders {
        return [
            "Accept": "application/json",
            "User-Agent": "iOS/\(UIDevice.current.systemVersion)"
        ]
    }
    
    func buildRequest(from endpoint: NDEndpoint) throws -> URLRequest {
        // 构建完整URL
        let urlString = endpoint.domain.baseURL + endpoint.path
        guard var urlComponents = URLComponents(string: urlString) else {
            throw NDNetworkError.invalidURL
        }
        
        // 添加公共参数到查询字符串
        var queryItems = urlComponents.queryItems ?? []
        commonParameters.forEach { key, value in
            queryItems.append(URLQueryItem(name: key, value: "\(value)"))
        }
        urlComponents.queryItems = queryItems
        
        guard let url = urlComponents.url else {
            throw NDNetworkError.invalidURL
        }
        
        // 创建URLRequest
        var request = URLRequest(url: url)
        request.httpMethod = endpoint.method.rawValue
        
        // 设置头部
        commonHeaders.forEach { request.setValue($0.value, forHTTPHeaderField: $0.name) }
        request.setValue(endpoint.contentType.headerValue, forHTTPHeaderField: "Content-Type")
        endpoint.headers?.forEach { request.setValue($0.value, forHTTPHeaderField: $0.name) }
        
        // 设置请求体
        if let parameters = endpoint.parameters {
            do {
                request = try endpoint.contentType.encoding.encode(request, with: parameters)
            } catch {
                throw NDNetworkError.encodingFailed
            }
        }
        
        print("🌐 Request: \(request.url?.absoluteString ?? "Unknown URL")")
        print("📤 Parameters: \(endpoint.parameters ?? [:])")
        
        return request
    }
}

// MARK: - Bundle 扩展
extension Bundle {
    var appVersion: String {
        infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0"
    }
}

struct EmptyTemp: Codable {}

